package locale

import (
	"context"
	"gf-demo/internal/consts"
	"gf-demo/internal/logic/util"
	"gf-demo/internal/model"
	"gf-demo/internal/service"
	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/i18n/gi18n"
)

type (
	sLocale struct{}
)

func init() {
	service.RegisterLocale(New())
}

func New() service.ILocale {
	return &sLocale{}
}

// SetLocale 设置全局Locale
// param: ctx-上下文 | setLocale-DTO
func (s *sLocale) SetLocale(ctx context.Context, setLocale model.SetLocale) error {
	locale := setLocale.Locale
	ctxR, b, cErr := s.CheckLocale(ctx, locale)
	if !b {
		return cErr
	}
	consts.DefaultLocale = locale
	res := consts.I18n.Tf(ctxR, `locale_global_change`, locale)
	if res == "" {
		return gerror.NewCode(gcode.CodeNotFound, consts.I18n.T(ctxR, `locale_not_exist`))
	}
	return gerror.NewCode(gcode.CodeOK, res)
}

// T 使用系统当前默认语言进行翻译
// param: ctx-上下文 | i18nKey-对应i18n文件中的key
func (s *sLocale) T(ctx context.Context, i18nKey string) (string, error) {
	return s.TW(ctx, consts.DefaultLocale, i18nKey)
}

// Tf 使用系统当前默认语言进行翻译(i18n中含变量)
// param: ctx-上下文 | i18nKey-对应i18n文件中的key | values-i18nKey中对应的变量
func (s *sLocale) Tf(ctx context.Context, i18nKey string, values ...interface{}) (string, error) {
	return s.TF(ctx, consts.DefaultLocale, i18nKey, values)
}

// TW 使用指定语言进行翻译
// param: ctx-上下文 | locale-语言名称(如en、zh-CN、zh-TW) | i18nKey-对应i18n文件中的key
func (s *sLocale) TW(ctx context.Context, locale string, i18nKey string) (res string, err error) {
	ctxR, b, cErr := s.CheckLocale(ctx, locale)
	if !b {
		return "", cErr
	}
	return consts.I18n.T(ctxR, `{#`+i18nKey+`}`), gerror.NewCode(gcode.CodeOK, consts.I18n.T(ctxR, `translate_success`))
}

// TF 使用指定语言进行翻译(i18n中含变量)
// param: ctx-上下文 | locale-语言名称(如en、zh-CN、zh-TW) | i18nKey-对应i18n文件中的key | values-i18nKey中对应的变量
func (s *sLocale) TF(ctx context.Context, locale string, i18nKey string, values ...interface{}) (res string, err error) {
	ctxR, b, cErr := s.CheckLocale(ctx, locale)
	if !b {
		return "", cErr
	}
	return consts.I18n.Tf(ctxR, `{#`+i18nKey+`}`, values), gerror.NewCode(gcode.CodeOK, consts.I18n.T(ctxR, `translate_success`))
}

// WithLanguage 设置临时Locale
// param: ctx-上下文 | locale-语言名称(如zh-CN、en、zh-TW)
func (s *sLocale) WithLanguage(ctx context.Context, locale string) (ctxR context.Context) {
	ctxR = gi18n.WithLanguage(ctx, locale)
	return
}

// CheckLocale 判断系统是否有对应的Locale
// param: ctx-上下文 | locale-语言名称(如en、zh-CN、zh-TW)
func (s *sLocale) CheckLocale(ctx context.Context, locale string) (ctxR context.Context, b bool, err error) {
	b = util.ContainsGeneric(consts.LocaleList, locale)
	if b {
		ctxR = gi18n.WithLanguage(ctx, locale)
		err = gerror.NewCode(gcode.CodeOK, consts.I18n.Tf(ctxR, `locale_sys_contains`, locale))
	} else {
		ctxR = gi18n.WithLanguage(ctx, consts.DefaultLocale)
		err = gerror.NewCode(gcode.CodeNotFound, consts.I18n.Tf(ctxR, `locale_sys_not_contains`, consts.DefaultLocale))
	}
	return
}
